package top.surgeqi.security.demo.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
import top.surgeqi.security.demo.bean.po.Authority;
import top.surgeqi.security.demo.bean.po.Role;
import top.surgeqi.security.demo.bean.po.UserAccount;
import top.surgeqi.security.demo.bean.po.UserBinding;
import top.surgeqi.security.demo.dao.AuthorityMapper;
import top.surgeqi.security.demo.dao.RoleMapper;
import top.surgeqi.security.demo.dao.UserAccountMapper;
import top.surgeqi.security.demo.dao.UserBindingMapper;
import top.surgeqi.security.demo.service.UserAccountService;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p><em>Created by qipp on 2020/2/27 14:36</em></p>
 * 用户账户ServiceImpl
 *
 * @author <a href="https://gitee.com/qipengpai">qipp</a>
 * @since 1.0.1
 */
@Slf4j
@Service
public class UserAccountServiceImpl implements UserAccountService {

    /**
     * 用户账户Mapper
     */
    private final UserAccountMapper userAccountMapper;

    /**
     * 用户绑定Mapper
     */
    private final UserBindingMapper userBindingMapper;

    /**
     * 用户角色Mapper
     */
    private final RoleMapper roleMapper;

    /**
     * 用户权限Mapper
     */
    private final AuthorityMapper authorityMapper;

    public UserAccountServiceImpl(UserAccountMapper userAccountMapper,
                                  UserBindingMapper userBindingMapper,
                                  RoleMapper roleMapper,
                                  AuthorityMapper authorityMapper) {
        this.userAccountMapper = userAccountMapper;
        this.roleMapper = roleMapper;
        this.authorityMapper = authorityMapper;
        this.userBindingMapper = userBindingMapper;
    }

    /**
     * 根据用户名或手机号查询用户账户
     * {@inheritDoc}
     */
    @Override
    public UserAccount selectByUserName(String username) {
        // 根据用户名查询用户账户
        return userAccountMapper.selectByUserName(username);
    }

    /**
     * 根据手机号查询用户账户
     * {@inheritDoc}
     */
    @Override
    public UserAccount selectByPhone(String phone) {
        // 根据手机号查询用户账户
        return userAccountMapper.selectByPhone(phone);
    }

    /**
     * 查询绑定微信ID的用户账户信息
     * {@inheritDoc}
     */
    @Override
    public UserAccount selectWeChatUnionId(String unionId) {

        // 获取绑定微信的用户ID
        UserBinding userBinding = userBindingMapper.selectWeChatUnionId(unionId);
        // 微信未绑定用户
        if (null == userBinding) {
            log.error("微信未绑定用户 unionId -> {}", unionId);
            return null;
        }
        // 查询用户账户信息
        return userAccountMapper.selectById(userBinding.getAccountId());
    }

    /**
     * 组合用户账户对象与角色权限
     * {@inheritDoc}
     */
    @Override
    public UserAccount composeUserDetailsAndAuthority(UserAccount userAccount) {
        // 查询用户角色
        List<Role> roleList = roleMapper.selByUserId(userAccount.getMid());
        log.debug("获取启用角色集合{}", roleList);
        // 角色权限集合
        List<GrantedAuthority> authorities = new ArrayList<>(roleList);
        // 权限临时集合
        List<Authority> radAuthoritiesList = new ArrayList<>();
        for (Role role : roleList) {
            // 根据角色id查询权限集合
            List<Authority> radAuthorities = authorityMapper.selByRoleId(role.getMid()).stream().distinct().collect(Collectors.toList());
            log.info("权限集合（去重后的）{}", radAuthorities);
            boolean j = radAuthoritiesList.addAll(radAuthorities);
            log.debug("拼接权限集合{}，{}", j, radAuthoritiesList);
        }
        authorities.addAll(radAuthoritiesList);
        log.info("拼接角色和权限后的oauth权限结合{}", authorities);
        // 设置用户角色权限集合
        userAccount.setAuthorities(authorities);
        return userAccount;
    }
}
